package org.bmi.gwt.examples.servertoclient.client;

import org.bmi.gwt.examples.servertoclient.shared.ElementProxy;
import org.bmi.gwt.examples.servertoclient.shared.PrinterObject;
import org.bmi.gwt.examples.servertoclient.shared.PrinterProxy;
import org.bmi.gwt.mi.client.channel.Connection;
import org.bmi.gwt.mi.client.events.ConnectionHandler;
import org.bmi.gwt.mi.shared.BroadChannel;
import org.bmi.gwt.mi.shared.Channel;
import org.bmi.gwt.mi.shared.MiTransaction;
import org.bmi.gwt.mi.shared.callbacks.BindCallback;
import org.bmi.gwt.mi.shared.exceptions.InvalidArgumentException;
import org.bmi.gwt.mi.shared.exceptions.MiException;
import org.bmi.gwt.mi.shared.exceptions.NameParseException;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.RootPanel;

public class ServerToClientTest implements EntryPoint
{
	/*
	 * This example shows how queues can be created on server side, and how from
	 * client side are consumed messages produced on server side, and the
	 * opposite.
	 */

	@Override
	public void onModuleLoad()
	{
		Connection.createConnection(new ConnectionHandler()
		{
			@Override
			public void onException(Exception e)
			{
				GWT.log("an error occurred: ", e);
			}

			@Override
			public void onConnectionBegin(Connection connection)
			{
				try
				{
					/*
					 * 2 queue are created: the first is used to listen incoming
					 * messages, and the second is used to produce messages
					 * addressed to an object, provided by its ID.
					 */

					Channel qListen = connection.getChannel("org.bmi.gwt.mi.test.s2c.client");
					qListen.register("client_printer_id", new PrinterObject()
					{
						@Override
						public void print(String str)
						{
							RootPanel rootPanel = RootPanel.get();
							Element body = rootPanel.getElement();

							body.appendChild(Document.get().createTextNode(str));
							body.appendChild(Document.get().createBRElement());
						}
					});

					final BroadChannel qSend = connection.getChannel("org.bmi.gwt.mi.test.s2c.server");
					final PrinterProxy printerPrx = qSend.proxyToObject(PrinterProxy.class, "server_printer_id");

					qListen.bind(new BindCallback()
					{
						@Override
						public void onError(MiException error)
						{
							GWT.log("An error occurred: " + error);
						}

						@Override
						public void onBound(Channel channel)
						{
							MiTransaction t = qSend.createTransaction();
							try
							{
								/*
								 * Trying several constructors for several
								 * objects, and pushing all further method
								 * invocations to the client.
								 */

								ElementProxy p1 = t.proxyToNewObject(ElementProxy.class);
								p1.setStr("provided string");
								p1.setPrinter(printerPrx);

								/*
								 * The constructor takles as argument a return
								 * value from a function
								 */
								ElementProxy p2 = t.proxyToNewObject(ElementProxy.class, p1.getStr());
								p2.setPrinter(printerPrx);

								/*
								 * This is an example of constructor taking a
								 * proxy as argument
								 */
								ElementProxy p3 = t.proxyToNewObject(ElementProxy.class, "String from constructor",
										printerPrx);

								p1.print();
								p2.print();
								p3.print();
							}
							catch (InvalidArgumentException e)
							{
								GWT.log("", e);
							}

							t.commit();
						}
					});
				}
				catch (NameParseException e)
				{
					e.printStackTrace();
				}
			}
		});
	}
}
